import 'dart:async';
import 'dart:typed_data';
import 'package:dio/dio.dart';
import 'package:flutter/foundation.dart' show kIsWeb;
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:http_parser/http_parser.dart'; // 解析 MediaType

// Web 端依赖
// ignore: avoid_web_libraries_in_flutter
import 'dart:html' as html show FileUploadInputElement, FileReader, Blob, Url;

// 移动端依赖
import 'dart:io';
import 'package:image_cropper/image_cropper.dart';
import 'package:flutter_image_compress/flutter_image_compress.dart';

abstract class ImagePickerHelper {
  static const _maxFileSize = 5 * 1024 * 1024; // 5MB
  static final _picker = ImagePicker();

  /// 统一入口：选择并处理图片
  static Future<XFile?> pickAndProcessImage() async {
    try {
      return kIsWeb ? await _processWebImage() : await _processMobileImage();
    } catch (e) {
      debugPrint('图片处理异常: $e');
      rethrow;
    }
  }

  /// Web 端处理流程
  static Future<XFile?> _processWebImage() async {
    // 只允许选择图片
    final input = html.FileUploadInputElement()
      ..accept = 'image/*'
      ..multiple = false;
    input.click();

    final completer = Completer<XFile?>();
    input.onChange.listen((event) async {
      final file = input.files?.first;
      if (file == null) {
        completer.complete(null);
        return;
      }

      if (file.size > _maxFileSize) {
        completer.completeError('文件大小超过5MB限制');
        return;
      }

      final reader = html.FileReader();
      reader.readAsArrayBuffer(file);
      reader.onLoadEnd.listen((e) async {
        final bytes = reader.result as Uint8List?;
        if (bytes == null) {
          completer.complete(null);
          return;
        }
        final blob = html.Blob([bytes], file.type);
        final url = html.Url.createObjectUrlFromBlob(blob);
        //封装文件的 URL 和文件名
        completer.complete(XFile(url, name: file.name));
      });
    });
    return completer.future;
  }

  /// 移动端处理流程（先裁剪后压缩）
  static Future<XFile?> _processMobileImage() async {
    // 1. 选择图片
    final pickedFile = await _picker.pickImage(source: ImageSource.gallery);
    if (pickedFile == null) return null;

    // 2. 裁剪图片
    final croppedFile = await _cropImage(File(pickedFile.path));
    if (croppedFile == null) return null;

    // 3. 自动压缩直到符合大小
    return await _compressImageIfNeeded(croppedFile);
  }

  /// 图片裁剪
  static Future<File?> _cropImage(File originalFile) async {
    try {
      final cropped = await ImageCropper().cropImage(
        sourcePath: originalFile.path,
        aspectRatioPresets: [CropAspectRatioPreset.square], //设置为正方形裁剪
        compressQuality: 100,
        uiSettings: [
          AndroidUiSettings(
            toolbarTitle: '裁剪图片',
            toolbarColor: const Color.fromARGB(255, 93, 190, 231),
            hideBottomControls: true,
            initAspectRatio: CropAspectRatioPreset.square,
          ),
          IOSUiSettings(
            title: '裁剪图片',
            resetButtonHidden: true,
          ),
        ],
      );
      return cropped?.path != null ? File(cropped!.path) : null;
    } catch (e) {
      debugPrint('裁剪失败: $e');
      return null;
    }
  }

  /// 智能压缩图片（修复空安全）
  static Future<XFile?> _compressImageIfNeeded(File file) async {
    int quality = 90;
    Uint8List? bytes = await file.readAsBytes();

    // 添加空检查
    if (bytes.isEmpty) return null;

    while (bytes!.lengthInBytes > _maxFileSize && quality >= 50) {
      debugPrint('压缩质量: $quality%');
      final compressedBytes = await FlutterImageCompress.compressWithList(
        bytes,
        quality: quality,
        minHeight: 800,
        minWidth: 800,
      );

      // 添加压缩结果检查
      if (compressedBytes.isEmpty) break;

      bytes = compressedBytes;
      quality -= 20;
    }

    if (bytes.isEmpty) return null;

    // 写入临时文件
    final dir = Directory.systemTemp;
    final target = File(
        '${dir.path}/compressed_${DateTime.now().millisecondsSinceEpoch}.jpg');
    await target.writeAsBytes(bytes);

    return XFile(target.path);
  }

  // 处理图片文件上传时
  static Future<MultipartFile?> convertXFileToMultipart(XFile file) async {
    final mimeType = lookupMimeType(file.name) ?? 'application/octet-stream';
    if (kIsWeb) {
      // Web 端需要读取字节数据
      final bytes = await file.readAsBytes();
      return MultipartFile.fromBytes(bytes,
          filename: file.name, contentType: MediaType.parse(mimeType));
    } else {
      // 移动端直接使用本地文件路径
      return MultipartFile.fromFile(file.path,
          filename: file.name, contentType: MediaType.parse(mimeType));
    }
  }

  // 上传完成后，文件内存释放
  static Future<void> releaseImage(XFile? file) async {
    if (file == null) return;
    try {
      if (kIsWeb) {
        // Web 端：释放 Blob URL
        html.Url.revokeObjectUrl(file.path);
      } else {
        // 移动端：删除本地文件
        final fileToDelete = File(file.path);
        if (await fileToDelete.exists()) {
          await fileToDelete.delete();
        }
      }
      return;
    } catch (e) {
      debugPrint('释放文件失败: $e');
      throw Exception('释放文件失败: $e');
    }
  }

  // 仅支持的图片格式
  static final Map<String, String> _imageMimeTypes = {
    'jpeg': 'image/jpeg',
    'jpg': 'image/jpg',
    'png': 'image/png',
    'webp': 'image/webp',
  };

  // 获取文件的 MIME 类型
  static lookupMimeType(String filename) {
    final extension = filename.split('.').last.toLowerCase();
    return _imageMimeTypes[extension];
  }
}
